import logging

from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *

from protolib.gui_utils.pyqt5_messageboxes import show_question_messagebox

from windows.to_protolib.text_input import ask_text

logger = logging.getLogger(__name__)

class ConfigureWindow(QDialog):
    updating = False

    def __init__(self, file_browser):
        super().__init__()

        # Initialize tab screen
        self.tabs = QTabWidget()
        self.typing_tabs = QTabWidget()
        self.typing_types_tab = QWidget()
        self.typing_mimetypes_tab = QWidget()

        self.file_browser = file_browser

        #region typing types tab
        types_tab_layout = QVBoxLayout()

        self.file_type_select = QComboBox()
        sorted_file_types = self.typing_types_refresh_select()
        self.file_type_select.activated.connect(self.file_type_select_updated)
        types_tab_layout.addWidget(self.file_type_select)

        types_tab_type_controls_layout = QHBoxLayout()
        self.mimetypes_type_remove = QPushButton('Remove File Type')
        self.mimetypes_type_remove.clicked.connect(self.typing_types_remove_type)
        types_tab_type_controls_layout.addWidget(self.mimetypes_type_remove)
        self.mimetypes_type_add = QPushButton('Add File Type')
        self.mimetypes_type_add.clicked.connect(self.typing_types_add_type)
        types_tab_type_controls_layout.addWidget(self.mimetypes_type_add)
        types_tab_layout.addLayout(types_tab_type_controls_layout)

        types_tab_viewer_layout = QHBoxLayout()
        self.file_type_viewer_label = QLabel('Viewer')
        types_tab_viewer_layout.addWidget(self.file_type_viewer_label)
        self.file_type_viewer = QLineEdit(self.file_browser.config['typing']['types'][sorted_file_types[0]]['viewer'] if sorted_file_types else '')
        self.file_type_viewer.editingFinished.connect(self.file_type_viewer_changed)
        self.file_type_viewer.setPlaceholderText('Enter type viewer command here')
        types_tab_viewer_layout.addWidget(self.file_type_viewer)
        types_tab_layout.addLayout(types_tab_viewer_layout)

        types_tab_mimetype_layout = QHBoxLayout()
        self.mimetypes_mimetype_label = QLabel('Mime Types')
        types_tab_mimetype_layout.addWidget(self.mimetypes_mimetype_label)
        self.mimetypes_edit = QComboBox()
        self.mimetypes_edit.editTextChanged.connect(self.mimetype_assoc_edited)
        types_tab_mimetype_layout.addWidget(self.mimetypes_edit)
        types_tab_layout.addLayout(types_tab_mimetype_layout)

        types_tab_mimetype_controls_layout = QHBoxLayout()
        self.typing_types_mimetype_remove = QPushButton('Remove Mime Type')
        self.typing_types_mimetype_remove.clicked.connect(self.typing_types_remove_mimetype)
        types_tab_mimetype_controls_layout.addWidget(self.typing_types_mimetype_remove)
        self.typing_types_mimetype_add = QPushButton('Add Mime Type')
        self.typing_types_mimetype_add.clicked.connect(self.typing_types_add_mimetype)
        types_tab_mimetype_controls_layout.addWidget(self.typing_types_mimetype_add)
        types_tab_layout.addLayout(types_tab_mimetype_controls_layout)

        self.typing_types_tab.setLayout(types_tab_layout)

        self.file_type_select_updated()
        #endregion

        #region typing mimetypes tab
        mimetypes_tab_layout = QVBoxLayout()

        self.mimetype_select = QComboBox()
        sorted_mimetypes = self.typing_mimetypes_refresh_select()
        self.mimetype_select.activated.connect(self.mimetype_select_updated)
        mimetypes_tab_layout.addWidget(self.mimetype_select)

        mimetypes_tab_type_controls_layout = QHBoxLayout()
        self.mimetypes_type_remove = QPushButton('Remove Mime Type')
        self.mimetypes_type_remove.clicked.connect(self.typing_mimetypes_remove_type)
        mimetypes_tab_type_controls_layout.addWidget(self.mimetypes_type_remove)
        self.mimetypes_type_add = QPushButton('Add Mime Type')
        self.mimetypes_type_add.clicked.connect(self.typing_mimetypes_add_type)
        mimetypes_tab_type_controls_layout.addWidget(self.mimetypes_type_add)
        mimetypes_tab_layout.addLayout(mimetypes_tab_type_controls_layout)

        mimetypes_tab_name_layout = QHBoxLayout()
        self.mimetype_name_label = QLabel('Name')
        mimetypes_tab_name_layout.addWidget(self.mimetype_name_label)
        self.mimetype_name = QLineEdit(self.file_browser.config['typing']['mimetypes'][sorted_mimetypes[0]]['name'] if sorted_mimetypes else '')
        self.mimetype_name.editingFinished.connect(self.mimetype_name_changed)
        self.mimetype_name.setPlaceholderText('Enter mime type name here')
        mimetypes_tab_name_layout.addWidget(self.mimetype_name)
        mimetypes_tab_layout.addLayout(mimetypes_tab_name_layout)

        mimetypes_tab_mimetype_layout = QHBoxLayout()
        self.mimetypes_mimetype_label = QLabel('Patterns')
        mimetypes_tab_mimetype_layout.addWidget(self.mimetypes_mimetype_label)
        self.mimetypes_select = QComboBox()
        self.mimetypes_select.editTextChanged.connect(self.mimetype_pattern_edited)
        mimes = self.file_browser.config['typing']['mimetypes'][sorted_mimetypes[0]]['patterns']
        self.mimetypes_select.addItems(sorted(mimes))
        mimetypes_tab_mimetype_layout.addWidget(self.mimetypes_select)
        mimetypes_tab_layout.addLayout(mimetypes_tab_mimetype_layout)

        mimetypes_tab_mimetype_controls_layout = QHBoxLayout()
        self.typing_mimetypes_mimetype_remove = QPushButton('Remove Pattern')
        self.typing_mimetypes_mimetype_remove.clicked.connect(self.typing_mimetypes_remove_mimetype)
        mimetypes_tab_mimetype_controls_layout.addWidget(self.typing_mimetypes_mimetype_remove)
        self.typing_mimetypes_mimetype_add = QPushButton('Add Pattern')
        self.typing_mimetypes_mimetype_add.clicked.connect(self.typing_mimetypes_add_mimetype)
        mimetypes_tab_mimetype_controls_layout.addWidget(self.typing_mimetypes_mimetype_add)
        mimetypes_tab_layout.addLayout(mimetypes_tab_mimetype_controls_layout)

        self.typing_mimetypes_tab.setLayout(mimetypes_tab_layout)

        self.mimetype_select_updated()
        #endregion

        # Add tabs
        self.tabs.addTab(self.typing_tabs,"File Typing")
        self.typing_tabs.addTab(self.typing_types_tab,"Types")
        self.typing_tabs.addTab(self.typing_mimetypes_tab,"Mime Types")

        # Add tabs to widget
        layout = QVBoxLayout()
        self.setLayout(layout)
        self.layout().addWidget(self.tabs)

    def file_type_select_updated(self):
        self.updating = True
        index = self.file_type_select.currentIndex()
        key = self.file_type_select.itemText(index)
        viewer = self.file_browser.config['typing']['types'][key]['viewer']
        self.file_type_viewer.setText(viewer if viewer else '')
        mimes = self.file_browser.config['typing']['types'][key]['mimetypes']
        self.mimetypes_edit.clear()
        if len(mimes) > 0:
            self.mimetypes_edit.addItems(sorted(mimes))
            self.mimetypes_edit.setEditable(True)
        else:
            self.mimetypes_edit.setEditable(False)
        self.updating = False

    def file_type_viewer_changed(self):
        if self.updating:
            return
        index = self.file_type_select.currentIndex()
        key = self.file_type_select.itemText(index)
        viewer = self.file_type_viewer.text()
        self.file_browser.config['typing']['types'][key]['viewer'] = viewer if viewer else None

    def mimetype_assoc_edited(self, text):
        key_index = self.file_type_select.currentIndex()
        key = self.file_type_select.itemText(key_index)
        index = self.mimetypes_edit.currentIndex()
        if not text:
            return
        self.file_browser.config['typing']['types'][key]['mimetypes'][index] = text

    def typing_types_remove_mimetype(self):
        response = show_question_messagebox('Are you sure?', 'You are about to permanently delete a mime type association. This can\'t be undone')
        if not response:
            return
        index = self.mimetypes_edit.currentIndex()
        self.mimetypes_edit.removeItem(index)
        self.mimetype_assoc_edited(None)

    def typing_types_add_mimetype(self):
        text = ask_text('Enter mime type', 'Use the following field to enter the mime type you would like to add', 'Enter mime type here')
        if not text:
            return
        self.mimetypes_edit.addItem(text)
        self.mimetype_assoc_edited(text)
        self.file_type_select_updated()

    def typing_types_remove_type(self):
        response = show_question_messagebox('Are you sure?', 'You are about to permanently delete a file type record. This can\'t be undone')
        if not response:
            return

    def typing_types_add_type(self):
        text = ask_text('Enter file type name', 'Use the following field to enter the name of the file type you would like to add', 'Enter file type name here')
        if not text:
            return
        record = {
            'mimetypes': [],
            'viewer': None
        }
        self.file_browser.config['typing']['types'][text] = record
        self.typing_types_refresh_select()
        self.file_type_select_updated()

    def typing_types_refresh_select(self):
        self.file_type_select.clear()
        sorted_file_types = sorted(self.file_browser.config['typing']['types'].keys())
        self.file_type_select.addItems(sorted_file_types)
        return sorted_file_types

    def mimetype_select_updated(self):
        self.updating = True
        index = self.mimetype_select.currentIndex()
        key = self.mimetype_select.itemText(index)
        name = self.file_browser.config['typing']['mimetypes'][key]['name']
        self.mimetype_name.setText(name if name else '')
        mimes = self.file_browser.config['typing']['mimetypes'][key]['patterns']
        self.mimetypes_select.clear()
        if len(mimes) > 0:
            self.mimetypes_select.addItems(sorted(mimes))
            self.mimetypes_select.setEditable(True)
        else:
            self.mimetypes_select.setEditable(False)
        self.updating = False

    def mimetype_name_changed(self):
        if self.updating:
            return
        index = self.mimetype_select.currentIndex()
        key = self.mimetype_select.itemText(index)
        viewer = self.mimetype_viewer.text()
        self.file_browser.config['typing']['mimetypes'][key]['viewer'] = viewer if viewer else None

    def mimetype_name_edited(self, text):
        key_index = self.mimetype_select.currentIndex()
        key = self.mimetype_select.itemText(key_index)
        index = self.mimetypes_select.currentIndex()
        if not text:
            return
        self.file_browser.config['typing']['mimetypes'][key]['mimetypes'][index] = text

    def typing_mimetypes_remove_mimetype(self):
        response = show_question_messagebox('Are you sure?', 'You are about to permanently delete a mime type association. This can\'t be undone')
        if not response:
            return
        index = self.mimetypes_select.currentIndex()
        self.mimetypes_select.removeItem(index)
        self.mimetype_pattern_edited(None)

    def typing_mimetypes_add_mimetype(self):
        text = ask_text('Enter mime type', 'Use the following field to enter the mime type you would like to add', 'Enter mime type here')
        if not text:
            return
        self.mimetypes_select.addItem(text)
        self.mimetype_pattern_edited(text)
        self.mimetype_select_updated()

    def typing_mimetypes_remove_type(self):
        response = show_question_messagebox('Are you sure?', 'You are about to permanently delete a file type record. This can\'t be undone')
        if not response:
            return

    def typing_mimetypes_add_type(self):
        text = ask_text('Enter file type name', 'Use the following field to enter the name of the file type you would like to add', 'Enter file type name here')
        if not text:
            return
        record = {
            'mimetypes': [],
            'viewer': None
        }
        self.file_browser.config['typing']['mimetypes'][text] = record
        self.typing_mimetypes_refresh_select()
        self.mimetype_select_updated()

    def typing_mimetypes_refresh_select(self):
        self.mimetype_select.clear()
        sorted_mimetypes = sorted(self.file_browser.config['typing']['mimetypes'].keys())
        self.mimetype_select.addItems(sorted_mimetypes)
        return sorted_mimetypes

    def mimetype_pattern_edited(self, text):
        key_index = self.file_type_select.currentIndex()
        key = self.file_type_select.itemText(key_index)
        index = self.mimetypes_select.currentIndex()
        if not text:
            return
        self.file_browser.config['typing']['mimetypes'][key]['patterns'][index] = text

# To ProtoLib

# https://stackoverflow.com/questions/7479915/getting-all-items-of-qcombobox-pyqt4-python
def combo_box_all_items(widget: QComboBox):
    return [widget.itemText(i) for i in range(widget.count())]
